/**
 * Title:       AgentContainer.java
 * Copyright:   Copyright (c) 1996-2004 The Agent Factory Working Group. All rights reserved.
 * Licence:     This file is free software; you can redistribute it and/or modify
 *              it under the terms of the GNU Lesser General Public License as published by
 *              the Free Software Foundation; either version 2.1, or (at your option)
 *              any later version.
 *
 *              This file is distributed in the hope that it will be useful,
 *              but WITHOUT ANY WARRANTY; without even the implied warranty of
 *              MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *              GNU Lesser General Public License for more details.
 *
 *              You should have received a copy of the GNU Lesser General Public License
 *              along with Agent Factory; see the file COPYING.  If not, write to
 *              the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 *              Boston, MA 02111-1307, USA.
 */
package com.agentfactory.platform.core;

import com.agentfactory.platform.core.Agent;
import com.agentfactory.platform.AgentPlatform;
import com.agentfactory.platform.util.Logger;

import java.util.ArrayList;
import java.util.Observable;

/**
 * A container for all classes running on the Platform.
 *
 * @author Rem Collier
 */
public class AgentContainer extends Observable {
    private static final int CLASS_LOG_LEVEL = Logger.LEVEL_ERROR;

    private ArrayList agents;
    
    /**
     * Create an agent container, initialising the container, and setting the
     * parent platform.
     */
    public AgentContainer(AgentPlatform platform) {
        agents = new ArrayList();
    }
    
    /**
     * Add an agent to the agent container, notifiying any observers of the
     * update.
     */
    public synchronized void add(Agent inAgent, String inName) {
        agents.add(inAgent);
        
        notify("newAgent " + inName);
    }
    
    
    /**
     * Get a list of all agents held in the container.
     */
    public synchronized ArrayList getAgents() {
        ArrayList list = new ArrayList();
        
        for (int i=0; i < agents.size(); i++) {
            list.add(agents.get(i));
        }
        
        return list;
    }
    
    /**
     * Get a specific agent from the container.
     */
    public synchronized Agent get(String name) {
        Agent agent = null;
        
        boolean found = false;
        int index = 0;
        while ((index < agents.size()) && !found) {
            agent = (Agent) agents.get(index++);
            found = agent.getName().equals(name);
        }
        
        return agent;
    }
    
    /**
     * Resume an agent's actions.
     */
    public synchronized boolean resume( String name ) {
        Agent agent = get( name );
        
        if ( agent == null ) {
            Logger.detail( "[AgentContainer] Could not resume agent: " + name, CLASS_LOG_LEVEL );
            return false;
        }
        agent.resume();
        
        notify( "resume " + name );
        return true;
    }
    
    /**
     * Suspend an agent.
     */
    public synchronized boolean suspend(String name) {
        Agent agent = get(name);
        
        if (agent == null) {
            Logger.detail( "[AgentContainer] Could not suspend agent: " + name, CLASS_LOG_LEVEL );
            return false;
        }
        
        agent.suspend();
        notify("suspend " + name);
        return true;
    }
    
    /**
     * Terminate an agent.
     */
    public synchronized boolean terminate(String name) {
        Agent agent = get(name);
        if (agent == null) {
            Logger.detail( "[AgentContainer] Could not terminate agent: " + name, CLASS_LOG_LEVEL );
            return false;
        }
        
        agents.remove(agent);
        terminate(agent);
        
        return true;
    }
    
    private synchronized void terminate(Agent agent) {
        agent.terminate();
        notify("terminate " + agent.getName());
    }
    
    public synchronized void terminateAllAgents() {
        for (int i = 0; i < agents.size(); i++) {
            terminate((Agent) agents.get(i));
        }
        agents.clear();
    }
    
    public synchronized boolean modify(String oldName, String newName) {
        Agent agent = get(oldName);
        
        if (agent == null) {
            return false;
        }
        
        agent.changeAIDName(newName);
        notify("refreshAgent " + oldName + " " + newName);
        return true;
    }
    
    /**
     * Returns a list of Strings that represent the agents that have platform
     * specific names.
     *
     * @return ArrayList
     */
    public ArrayList getPlatformSpecificAgentNames() {
        Agent agent = null;
        ArrayList list = new ArrayList();
        for (int i = 0; i < agents.size(); i++) {
            agent = (Agent) agents.get(i);
            if (agent.getName().indexOf('@') > -1) {
                list.add(agent.getName());
            }
        }
        return list;
    }
    
    public synchronized void notify(String message) {
        setChanged();
        notifyObservers(message);
    }
}
